package cn.biplam.back.operator.systemManage.sysprivi.role.table;

import java.util.ArrayList;

import cn.biplam.back.sql.dml.Delete;
import cn.biplam.back.sql.dml.Insert;
import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.interfaces.DataOperator;
import cn.biplam.common.opcode.SysManageCode.RolePriviOptCode;
import cn.biplam.common.struc.SysStruc.PriviStruc;
import cn.biplam.common.struc.SysStruc.RolePriviStruc;
import cn.biplam.common.struc.SysStruc.Role_Privi_Flag;
import cn.biplam.common.struc.SysStruc.UserRoleStruc;
import cn.biplam.common.wrapper.ErrorMessage;

/**
 *  角色权限表
 * @author XiaoRuxing Dec 9, 20093:00:20 PM
 * @version 1.0
 */
public class RolePriviOpt extends DataOperator{

	public RolePriviOpt() throws ErrorMessage {
		super(RolePriviStruc.Table_Name);
	}

	@Override
	protected OperatorResult _exchange() throws ErrorMessage {
		ArrayList<String> sql = new ArrayList<String>();
		if(RolePriviOptCode.Query_By_Role_ID.equals(opId)){
			this.queryByRoleId(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else if(RolePriviOptCode.Insert.equals(opId)){
			this.insert(sql, filter);
			return this.doing(sql,Operator_Type.DML);
		}else if(RolePriviOptCode.Delete.equals(opId)){
			this.delete(sql, filter);
			return this.doing(sql,Operator_Type.DML);
		}else if(RolePriviOptCode.Query_Role_Privi_Imme.equals(opId)){
			this.queryRolePriviImmediate(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else if(RolePriviOptCode.Query_By_Privi_ID.equals(opId)){
			this.queryByPriviId(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else if(RolePriviOptCode.Query_By_PriviAndRole_ID.equals(opId)){
			this.queryByRoleIdAndPriviId(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else if(RolePriviOptCode.Query_Privi_Child.equals(opId)){
			this.queryRolePriviChild(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else if(RolePriviOptCode.Query_RoleParticular_Privi.equals(opId)){
			this.queryRoleParticularPrivi(sql, filter);
			return this.doing(sql,Operator_Type.Select);
		}else{
			throw new ErrorMessage("Operator Exchange outport not found:"+ opId+" !");
		}
	}

	/** 
	 * 获取当前角色独有的权限
	 * 	select * 
 		from user_role a 
    	join role_privi b on a.role_id = b.role_id
 		where a.user_id = '251bc' 
 		and b.role_id = '2'
 		and b.privi_id not in
 		(select d.privi_id 
 			from user_role c 
    			join role_privi d on c.role_id = d.role_id
 		where c.user_id = '251bc' 
 		and d.role_id <> '2')
	 * <BR>参数名称:RolePriviStruc.Role_ID 
	 */
	private void queryRoleParticularPrivi(ArrayList<String> sql, DataFilter filter){
		String roleId= filter.getValue(RolePriviStruc.ROLE_ID);//角色ID
		String curUser = filter.getValue(UserRoleStruc.USER_ID);;
		StringBuilder sp = new StringBuilder();
		sp.append("select * from ");
		sp.append(UserRoleStruc.Table_Name+" a ");
		sp.append(" join "+this.tableName+" b on ");
		sp.append(" a."+UserRoleStruc.ROLE_ID+" = b."+RolePriviStruc.ROLE_ID);
		sp.append(" where a."+UserRoleStruc.USER_ID+"='"+curUser+"' ");
		sp.append(" and b."+RolePriviStruc.ROLE_ID+"='"+roleId+"' ");
		
		//TODO 子查询逻辑是一个完全相同的取反运算，应该是没有必要的
//		sp.append(" and b."+RolePriviStruc.PRIVI_ID+" not in (");
//		sp.append("select b."+RolePriviStruc.PRIVI_ID+" from ");
//		sp.append(UserRoleStruc.Table_Name+" a ");
//		sp.append(" join "+this.tableName+" b on ");
//		sp.append(" a."+UserRoleStruc.ROLE_ID+" = b."+RolePriviStruc.ROLE_ID);
//		sp.append(" where a."+UserRoleStruc.USER_ID+"='"+curUser+"' ");
//		sp.append(" and b."+RolePriviStruc.ROLE_ID+"<>'"+roleId+"' ");
//		sp.append(")");

		sql.add(sp.toString());
	}

	/**
	 *  获取角色权限表中指定权限的下级权限
	 */
	private void queryRolePriviChild(ArrayList<String> sql, DataFilter filter){
		String roleId= filter.getValue(RolePriviStruc.ROLE_ID);//角色ID
		String priviId = filter.getValue();//根权限ID
		StringBuilder sp = new StringBuilder();
		sp.append(" select b.* from ");
		sp.append(this.tableName);
		sp.append(" a join privi b on a.");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("=b.");
		sp.append(PriviStruc.PRIVI_ID);
		sp.append(" where a.");
		sp.append(RolePriviStruc.ROLE_ID);
		sp.append("='");
		sp.append(roleId);
		sp.append("' and ");
		sp.append(" b.");
		sp.append(PriviStruc.PRIVI_PARENT);
		sp.append("='");
		sp.append(priviId);
		sp.append("' ");
		sql.add(sp.toString());
	}

	/**
	 *  查询当前角色在指定权限为根节点下所具有的直接子权限<BR>
	 *  用于添加角色权限时过滤已经存在的权限(完全权限)
	 */
	private void queryRolePriviImmediate(ArrayList<String> sql, DataFilter filter){
		String roleId= filter.getValue(RolePriviStruc.ROLE_ID);//角色ID
		String priviId = filter.getValue();//根权限ID
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(this.tableName);
		sp.append(" a join privi b on a.");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("=b.");
		sp.append(PriviStruc.PRIVI_ID);
		sp.append(" where a.");
		sp.append(RolePriviStruc.ROLE_ID);
		sp.append("='");
		sp.append(roleId);
		sp.append("' and ");
		sp.append(" b.");
		sp.append(PriviStruc.PRIVI_PARENT);
		sp.append("='");
		sp.append(priviId);
		sp.append("' ");
		sp.append(" and a.");
		sp.append(RolePriviStruc.SUPPER_FLAG);
		sp.append("='");
		sp.append(Role_Privi_Flag.SUPPER);
		sp.append("'");
		sql.add(sp.toString());
	}

	/**
	 *  根据角色ID查询角色权限信息<BR>
	 *  参数名称:RoleIndexStruc.Role_ID
	 */
	private void queryByRoleId(ArrayList<String> sql , DataFilter filter){
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(this.tableName);
		sp.append(" a join privi b on a.");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("=b.");
		sp.append(PriviStruc.PRIVI_ID);
		sp.append(" where a.");
		sp.append(RolePriviStruc.ROLE_ID);
		sp.append("='");
		sp.append(filter.getValue(RolePriviStruc.ROLE_ID));
		sp.append("'");
		sql.add(sp.toString());
	}

	/**
	 *  根据权限ID查询角色权限信息<BR>
	 *  参数名称:RoleIndexStruc.PRIVI_ID,附加条件:RolePriviStruc.SUPPER_FLAG
	 */
	private void queryByPriviId(ArrayList<String> sql , DataFilter filter){
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(this.tableName);
		sp.append(" where ");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("='");
		sp.append(filter.getValue(RolePriviStruc.PRIVI_ID));
		sp.append("'");
		//角色完全权限标志位过滤
		String supperFlag = filter.getValue(RolePriviStruc.SUPPER_FLAG);
		if(supperFlag!=null){
			sp.append(" and ");
			sp.append(RolePriviStruc.SUPPER_FLAG);
			sp.append("='");
			sp.append(supperFlag);
			sp.append("'");
		}
		sql.add(sp.toString());
	}

	/**
	 *  根据角色ID和权限ID查询角色权限
	 *  参数名称:RoleIndexStruc.PRIVI_ID,附加条件:RolePriviStruc.ROLE_ID
	 */
	private void queryByRoleIdAndPriviId(ArrayList<String> sql, DataFilter filter){
		StringBuilder sp = new StringBuilder();
		sp.append(" select * from ");
		sp.append(this.tableName);
		sp.append(" where ");
		sp.append(RolePriviStruc.PRIVI_ID);
		sp.append("='");
		sp.append(filter.getValue(RolePriviStruc.PRIVI_ID));
		sp.append("' and ");
		sp.append(RolePriviStruc.ROLE_ID);
		sp.append("='");
		sp.append(filter.getValue(RolePriviStruc.ROLE_ID));
		sp.append("'");
		sql.add(sp.toString());
	}

	/**
	 *  创建角色权限
	 *  参数名称:RolePriviStruc.PRIVI_ID,RolePriviStruc.ROLE_ID,RolePriviStruc.SUPPER_FLAG
	 * @throws ErrorMessage 
	 */
	private void insert(ArrayList<String> sql , DataFilter filter) throws ErrorMessage{
		String rolePriviID = this.generatorRowID();
		Insert insert = new Insert(this.tableName);
		insert.putStringFieldDenyNull(RolePriviStruc.ID, rolePriviID);
		insert.putStringFieldDenyNull(RolePriviStruc.PRIVI_ID, filter.getValue(RolePriviStruc.PRIVI_ID));
		insert.putStringFieldDenyNull(RolePriviStruc.ROLE_ID, filter.getValue(RolePriviStruc.ROLE_ID));
		insert.putStringFieldDenyNull(RolePriviStruc.SUPPER_FLAG, filter.getValue(RolePriviStruc.SUPPER_FLAG));
		sql.add(insert.getSimpleSql());
	}

	/**
	 *  删除角色权限
	 * @throws ErrorMessage 
	 */
	private void delete(ArrayList<String> sql , DataFilter filter) throws ErrorMessage{
		Delete delete = new Delete(this.tableName);
		delete.setWhere(RolePriviStruc.ID+"='"+filter.getValue()+"'");
		sql.add(delete.getSimpleSql());
	}
}
